﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
using System.Configuration;
using System.Linq.Expressions;
using System.Threading;

namespace Sustainalytics.Reporting.BusinessLogic
{
    public class RepositoryAsync: IRepositoryAsync
    {
        public const string ConnectionStringName = "WiredTiger";
        public const string DatabaseName = "ClientDW_A";

        //private static readonly IMongoClient _client;
        private static readonly IMongoDatabase _database;

        //private RepositoryAsync() { }

        public static IRepositoryAsync GetInstance(string connectionString)
        {
            if (string.IsNullOrEmpty(connectionString))
                throw new ArgumentException(
                    "A connection string must be provided to create an mongoDbRepository instance!");

            return new RepositoryAsync();
        }

        static RepositoryAsync()
        {
            if (_database != null) return;

            var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;

            var client = new MongoClient(new MongoClientSettings
            {
                MaxConnectionPoolSize = 1000,
                Server = new MongoServerAddress("localhost", 27017)
            });

            _database = client.GetDatabase(DatabaseName);
        }

        public async Task<List<T>> List<T>(Expression<Func<T, bool>> filter, CancellationToken cancellationToken)
        {
            var collection = _database.GetCollection<T>(typeof(T).Name);

            var list = await collection.Find(filter).ToListAsync(cancellationToken);

            return list;
        }

        public async Task<Dictionary<TKey, TSource>> Dictionary<TKey, TSource>(Expression<Func<TSource, bool>> filter, Func<TSource,TKey> keySelector, CancellationToken cancellationToken)
        {
            var collection = _database.GetCollection<TSource>(typeof(TSource).Name);

            var source = await collection.Find(filter).ToListAsync(cancellationToken);

            return source.ToDictionary(keySelector);
        }

    }
}
